https://mp.weixin.qq.com/s/hOI-8UaOo4AP8AqokbDKHQ
在这篇文章中，了解到了Redux整个工作流程，当action发出之后，reducer立即算出state，整个过程是一个同步的操作

那么如果需要支持异步操作，或者支持错误处理、日志监控，这个过程就可以用上中间件

Redux中，中间件就是放在就是在dispatch过程，在分发action进行拦截处理，
其本质上一个函数，对store.dispatch方法进行了改造，在发出 Action和执行 Reducer这两步之间，添加了其他功能

<!-- 常用的中间件 -->
有很多优秀的redux中间件，这里我们例举两个：

redux-thunk：用于异步操作
redux-logger：用于日志记录,中间件函数实现日志记录的信息
上述的中间件都需要通过applyMiddlewares进行注册，作用是将所有的中间件组成一个数组，依次执行

然后作为第二个参数传入到createStore中
const store = createStore(
  reducer,
  applyMiddleware(thunk, logger)
);

<!-- redux-thunk -->
redux-thunk是官网推荐的异步处理中间件

默认情况下的dispatch(action)，action需要是一个JavaScript的对象

redux-thunk中间件会判断你当前传进来的数据类型，如果是一个函数，将会给函数传入参数值（dispatch，getState）

dispatch函数用于我们之后再次派发action
getState函数考虑到我们之后的一些操作需要依赖原来的状态，用于让我们可以获取之前的一些状态
所以dispatch可以写成下述函数的形式
<script>
  const getHomeMultidataAction
  return (dispatch) => {
  ) => {
  axios.get("http://xx.xx.xx.xx/test").then(res =
  const data = res.data.data;
  dispatch(changeBannersAction(data.banner.list)
  dispatch(changeRecommendsAction(data.recommend.list(C)
  })
}

</script>
Redux 中间件的这个中间，指的是 action 和 store 之间。
之前我们说过，在 redux 中， action 只能是一个对象，就因为它是对象，
因此直接把它派发给 store 。现在，当我们使用了 redux-thunk 之后， action 就可以是函数了。那为什么可以是函数呢？
看上面的图中不难发现， action 通过 dispatch 的方法，将数据递交给了 store 。
且 action 和 store 之间，是一个 dispatch 方法，那我们说的中间件 middleware ，实际上就是对 dispatch 方法的封装和升级。
对于最原始的 dispatch 方法来说，它会接收到一个 JS 对象并将其传递给 store 。
但如果我们传递的是一个 函数 的话，那么这个 dispatch 就升级了。
dispatch 不会直接把函数传递给 store ，它会通过 redux-thunk 中间件的方式，
先执行对应的函数，等执行到需要调用 store 的时候，再去调用 store 。

/* Redux-logger */
redux 的中间件非常的多，比如 redux-logger 可以记录 action 每一次派发的日志。那它怎么记录呢？
它在每一次调用 action 的时候，会通过 dispatch 方法把 action 传递给 store ，
之后呢，我们可以对 dispatch 做一个升级，让 dispatch 不仅把 action 传递给 store ，
而且在每一次传递之前，我们还通过 console.log 的方式将其打印出来，
这样的话，我们就写了一个 redux-logger 的中间件， 它可以在我们派发 action 的时候，把 action 打印在我们的控制台里面。

/* 实现原理 */
applyMiddlewares的源码
export default function applyMiddleware(...middlewares)
return (createStore) => (reducer, preloadedState, eenhancer)=>{
var store = createStore(reducer, preloadedState, enhancer)
var dispatch = store.dispatch;
var chain =
var middlewareAPI = {
  getState: store.getState,
  dispatch: (action) => dispatch(action)
};
chain = middlewares.map(middleware => middleware(miiddlewareAPI))
dispatch = compose(...chain)(store.dispatch);
return {...store, dispatch}
所有中间件被放进了一个数组chain，然后嵌套执行，最后执行store.dispatch。
可以看到，中间件内部（middlewareAPI）可以拿到getState和dispatch这两个方法

